package com.profgj.profgj.controller;

import com.profgj.profgj.entity.Product;
import com.profgj.profgj.enums.ServerStatus;
import com.profgj.profgj.service.ProductService;
import com.profgj.profgj.utils.EmptyUtils;
import com.profgj.profgj.utils.ReturnOperator;
import com.profgj.profgj.validater.ProductValidator;
import com.profgj.profgj.vo.EmptyObject;
import com.profgj.profgj.vo.ResultMsg;
import io.swagger.annotations.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;

/**
 * 对产品的增删改
 */
@RestController
@RequestMapping("/product")
@Api(tags = {"产品"},description = "产品")
public class ProductController {

    /**
     * 产品服务对象
     */
    @Resource
    private ProductService productService;

    /**
     * 返回空对象的替代品
     */
    private EmptyObject emptyObject = new EmptyObject();
    /**
     * 初始化产品参数校验器
     * @param binder
     */
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.setValidator(new ProductValidator());
    }

    /**
     * 查询所有产品
     * @return
     */
    @GetMapping("/product/all")
    @ApiOperation(value = "查询所有产品",consumes = "application/json", produces = "application/json")
    @ApiResponses({
            @ApiResponse(code = 200, message = "表明该请求被成功地完成,所请求的资源发送到客户端"),
            @ApiResponse(code = 401, message = "请求要求身份验证,常见于需要登录而用户未登录的情况"),
            @ApiResponse(code = 403, message = "服务器拒绝请求,常见于机密信息或复制其它登录而用户未登录的情况"),
            @ApiResponse(code = 404, message = "服务器无法取得所请求的网页,请求资源不存在"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public ResponseEntity<ResultMsg> queryAllProductMethod(){

        // 无条件查询所有产品
        List<Product> productList = productService.queryAll();
        if (!EmptyUtils.isProductListEmpty(productList)) {
            return ReturnOperator.createResultMsg("", ServerStatus.QUERY_MESSAGE_ERR, ServerStatus.ERROR,
                    new ArrayList(), emptyObject, HttpStatus.OK);
        }

        // 返回数据
        return ReturnOperator.createResultMsg(ServerStatus.QUERY_MESSAGE_SUCCESS, "", ServerStatus.OK,
                productList, emptyObject, HttpStatus.OK);
    }

    /**
     * 用户id查询该用户下的所有产品
     * @param userId
     * @return
     */
    @GetMapping("/product/all/{userId}")
    @ApiOperation(value = "用户id查询该用户下的所有产品",consumes = "application/json", produces = "application/json")
    @ApiImplicitParam(name = "userId", value = "用户id",required = true, dataType = "Integer", paramType = "Integer")
    @ApiResponses({
            @ApiResponse(code = 200, message = "表明该请求被成功地完成,所请求的资源发送到客户端"),
            @ApiResponse(code = 401, message = "请求要求身份验证,常见于需要登录而用户未登录的情况"),
            @ApiResponse(code = 403, message = "服务器拒绝请求,常见于机密信息或复制其它登录而用户未登录的情况"),
            @ApiResponse(code = 404, message = "服务器无法取得所请求的网页,请求资源不存在"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public ResponseEntity<ResultMsg> queryAllProductByUserIdMethod(@PathVariable("userId") Integer userId) {
        // Id参数校验
        if (!EmptyUtils.isIntegerEmpty(userId)){
            return ReturnOperator.createResultMsg("", ServerStatus.ID_NOT_NULL, ServerStatus.ERROR,
                    new ArrayList(), emptyObject, HttpStatus.OK);
        }

        // 用户id查询该用户下的所有产品
        List<Product> productList = productService.queryByUserId(userId);
        // 查询后的校验
        if (!EmptyUtils.isProductListEmpty(productList)) {
            return ReturnOperator.createResultMsg("", ServerStatus.QUERY_MESSAGE_ERR, ServerStatus.ERROR,
                    new ArrayList(), emptyObject, HttpStatus.OK);
        }

        // 返回数据
        return ReturnOperator.createResultMsg(ServerStatus.QUERY_MESSAGE_SUCCESS, "", ServerStatus.OK,
                productList, emptyObject, HttpStatus.OK);
    }

    /**
     * 添加产品
     * @param product   产品对象
     * @param errors    参数错误存储对象
     * @param session   回话session内部存储 user_id/role_id/user_name
     * @return
     */
    @PostMapping("/product")
    @ApiOperation(value = "添加产品",consumes = "application/json", produces = "application/json")
    @ApiResponses({
            @ApiResponse(code = 200, message = "表明该请求被成功地完成,所请求的资源发送到客户端"),
            @ApiResponse(code = 401, message = "请求要求身份验证,常见于需要登录而用户未登录的情况"),
            @ApiResponse(code = 403, message = "服务器拒绝请求,常见于机密信息或复制其它登录而用户未登录的情况"),
            @ApiResponse(code = 404, message = "服务器无法取得所请求的网页,请求资源不存在"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public ResponseEntity<ResultMsg> productAddMethod(@Valid @RequestBody Product product,
                                                      @ApiIgnore Errors errors,
                                                      @ApiIgnore HttpSession session) {
        // 对象参数校验
        if (errors.hasErrors()) {
            List<ObjectError> oes = errors.getAllErrors();
            for (ObjectError oe : oes) {
                if (oe instanceof FieldError) {
                    FieldError fe = (FieldError) oe;
                    return ReturnOperator.createResultMsg("", fe.getDefaultMessage(), ServerStatus.ERROR,
                            new ArrayList(), emptyObject, HttpStatus.OK);
                } else {
                    return ReturnOperator.createResultMsg("", oe.getDefaultMessage(), ServerStatus.ERROR,
                            new ArrayList(), emptyObject, HttpStatus.OK);
                }
            }
        }

        // 取得当前登录的用户角色id
        Integer role_id = Integer.valueOf(String.valueOf(session.getAttribute("role_id")));
        // 取得当前登录的用户id
        Integer user_id = Integer.valueOf(String.valueOf(session.getAttribute("user_id")));

        // 不是管理员的情况下
        if (role_id != 1) {
            // 添加企业关联
            product.setEnUserId(user_id);
        }

        // 将产品添加到数据库中
        Product product_new = productService.insert(product);
        if (!EmptyUtils.isProductEmpty(product_new)) {
            return ReturnOperator.createResultMsg("", ServerStatus.DATA_INSERT_ERR, ServerStatus.ERROR,
                    new ArrayList(), emptyObject, HttpStatus.OK);
        }

        // 返回数据
        return ReturnOperator.createResultMsg(ServerStatus.DATA_INSERT_SUCCESS, "", ServerStatus.OK,
                new ArrayList(), product_new, HttpStatus.OK);
    }

    /**
     * 修改产品
     * @param product   产品对象
     * @param errors    参数错误存储对象
     * @param session   回话session内部存储 user_id/role_id/user_name
     * @return
     */
    @PutMapping("/product")
    @ApiOperation(value = "修改产品",consumes = "application/json", produces = "application/json")
    @ApiResponses({
            @ApiResponse(code = 200, message = "表明该请求被成功地完成,所请求的资源发送到客户端"),
            @ApiResponse(code = 401, message = "请求要求身份验证,常见于需要登录而用户未登录的情况"),
            @ApiResponse(code = 403, message = "服务器拒绝请求,常见于机密信息或复制其它登录而用户未登录的情况"),
            @ApiResponse(code = 404, message = "服务器无法取得所请求的网页,请求资源不存在"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public ResponseEntity<ResultMsg> productChangeMethod(@Valid @RequestBody Product product,
                                                         @ApiIgnore Errors errors,
                                                         @ApiIgnore HttpSession session) {
        // 对象参数校验
        if (errors.hasErrors()) {
            List<ObjectError> oes = errors.getAllErrors();
            for (ObjectError oe : oes) {
                if (oe instanceof FieldError) {
                    FieldError fe = (FieldError) oe;
                    return ReturnOperator.createResultMsg("", fe.getDefaultMessage(), ServerStatus.ERROR,
                            new ArrayList(), emptyObject, HttpStatus.OK);
                } else {
                    return ReturnOperator.createResultMsg("", oe.getDefaultMessage(), ServerStatus.ERROR,
                            new ArrayList(), emptyObject, HttpStatus.OK);
                }
            }
        }
        // 取得当前登录的用户角色id
        Integer role_id = Integer.valueOf(String.valueOf(session.getAttribute("role_id")));
        // 取得当前登录的用户id
        Integer user_id = Integer.valueOf(String.valueOf(session.getAttribute("user_id")));

        // 不是管理员的情况下
        if (role_id != 1) {
            // 添加企业关联
            product.setEnUserId(user_id);
        }

        // 将产品添加到数据库中
        Product product_new = productService.update(product);
        if (!EmptyUtils.isProductEmpty(product_new)) {
            return ReturnOperator.createResultMsg("", ServerStatus.DATA_UPDATE_ERR, ServerStatus.ERROR,
                    new ArrayList(), emptyObject, HttpStatus.OK);
        }

        // 返回数据
        return ReturnOperator.createResultMsg(ServerStatus.DATA_UPDATE_SUCCESS, "", ServerStatus.OK,
                new ArrayList(), product_new, HttpStatus.OK);
    }

    /**
     * id删除产品
     * @param id    产品id
     * @param session   会话session内部存储 user_id/role_id/user_name
     * @return
     */
    @DeleteMapping("/product/{id}")
    @ApiOperation(value = "id删除产品",consumes = "application/json", produces = "application/json")
    @ApiImplicitParam(name = "id",value = "产品id",required = true, dataType = "Long", paramType = "Long", dataTypeClass = Long.class)
    @ApiResponses({
            @ApiResponse(code = 200, message = "表明该请求被成功地完成,所请求的资源发送到客户端"),
            @ApiResponse(code = 401, message = "请求要求身份验证,常见于需要登录而用户未登录的情况"),
            @ApiResponse(code = 403, message = "服务器拒绝请求,常见于机密信息或复制其它登录而用户未登录的情况"),
            @ApiResponse(code = 404, message = "服务器无法取得所请求的网页,请求资源不存在"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public ResponseEntity<ResultMsg> deleteProductByIdMethod(@PathVariable("id") Long id,
                                                       @ApiIgnore HttpSession session) {

        // 参数校验id
        if (!EmptyUtils.isLongEmpty(id)) {
            return ReturnOperator.createResultMsg("", ServerStatus.ID_NOT_NULL, ServerStatus.ERROR,
                    new ArrayList(), emptyObject, HttpStatus.OK);
        }

        // 删除判断
        if (!productService.deleteById(id)) {
            // 返回数据
            return ReturnOperator.createResultMsg("", ServerStatus.DATA_DELETE_ERR, ServerStatus.ERROR,
                    new ArrayList(), emptyObject, HttpStatus.OK);
        }

        // 返回数据
        return ReturnOperator.createResultMsg(ServerStatus.DATA_DELETE_SUCCESS, "", ServerStatus.OK,
                new ArrayList(), new Boolean(true), HttpStatus.OK);
    }

    /**
     * 删除产品列表
     * @param ids   产品列表id数组
     * @param session   会话session内部存储 user_id/role_id/user_name
     * @return
     */
    @DeleteMapping("/product")
    @ApiOperation(value = "删除产品列表",consumes = "application/json", produces = "application/json")
    @ApiImplicitParam(name = "ids",value = "产品id数组",required = true, dataType = "Long", paramType = "Long[]", dataTypeClass = Long.class)
    @ApiResponses({
            @ApiResponse(code = 200, message = "表明该请求被成功地完成,所请求的资源发送到客户端"),
            @ApiResponse(code = 401, message = "请求要求身份验证,常见于需要登录而用户未登录的情况"),
            @ApiResponse(code = 403, message = "服务器拒绝请求,常见于机密信息或复制其它登录而用户未登录的情况"),
            @ApiResponse(code = 404, message = "服务器无法取得所请求的网页,请求资源不存在"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public ResponseEntity<ResultMsg> deleteProductByIdsMethod(Long[] ids,@ApiIgnore HttpSession session) {

        // 参数校验id数组
        if (!EmptyUtils.isIdsEmpty(ids)) {
            return ReturnOperator.createResultMsg("", ServerStatus.ID_NOT_NULL, ServerStatus.ERROR,
                    new ArrayList(), emptyObject, HttpStatus.OK);
        }

        // 循环删除
        for (Long id : ids) {
            productService.deleteById(id);
        }

        // 返回数据
        return ReturnOperator.createResultMsg(ServerStatus.DATA_DELETE_SUCCESS, "", ServerStatus.OK,
                new ArrayList(), new Boolean(true), HttpStatus.OK);
    }
}
